package com.hzmg.netty;

import com.hzmg.netty.model.TestModel;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

/**
 * 客户端1
 */
public class SimpleClient {
    public static void main(String[] args) throws Exception {
        NioEventLoopGroup eventExecutors = new NioEventLoopGroup();
        try {
            //创建bootstrap对象（启动器）
            Bootstrap bootstrap = new Bootstrap();
            //设置线程组
            bootstrap.group(eventExecutors)
                    //设置客户端的通道实现类型
                    .channel(NioSocketChannel.class)
                    //使用匿名内部类初始化通道
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            //添加客户端通道的处理器
                            ch.pipeline().addLast(new StringEncoder())
                                    .addLast(new MyFirstClientHandler());
                        }
                    });
            /*//绑定端口号，启动客户端
            ChannelFuture channelFuture=bootstrap.bind(6666).sync();*/
            System.out.println("[nettyClientDemo]:客户端1启动完成");
            //连接服务端
            ChannelFuture channelFuture = bootstrap.connect("localhost", 8888).sync();
            //对通道关闭进行监听
            channelFuture.channel().closeFuture().sync();
        } finally {
            //关闭线程组
            eventExecutors.shutdownGracefully();
        }
    }

}

/**
 * 客户端2
 */
class SimpleClient2 {
    public static void main(String[] args) throws Exception {
        NioEventLoopGroup eventExecutors = new NioEventLoopGroup();
        try {
            //创建bootstrap对象（启动器）
            Bootstrap bootstrap = new Bootstrap();
            //设置线程组
            bootstrap.group(eventExecutors)
                    //设置客户端的通道实现类型
                    .channel(NioSocketChannel.class)
                    //使用匿名内部类初始化通道
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            //添加客户端通道的处理器
                            ch.pipeline().addLast(new ObjectEncoder())
                                    .addLast(new ObjectClientHandler());
                        }
                    });
            /*//绑定端口号，启动客户端
            ChannelFuture channelFuture=bootstrap.bind(6666).sync();*/
            System.out.println("[nettyClientDemo]:客户端2启动完成");
            //连接服务端
            ChannelFuture channelFuture = bootstrap.connect("localhost", 8888).sync();
            //对通道关闭进行监听
            channelFuture.channel().closeFuture().sync();
        } finally {
            //关闭线程组
            eventExecutors.shutdownGracefully();
        }
    }

}

/**
 * 发送字符串示例demo
 */
class MyFirstClientHandler extends ChannelInboundHandlerAdapter {
    private TestModel getTestModelObject() {
        TestModel testModel = new TestModel();
        testModel.setId(1);
        testModel.setName("zbw");
        return testModel;
    }
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //发送消息到客户端
        //ctx.writeAndFlush(Unpooled.copiedBuffer("客户端消息传递", CharsetUtil.UTF_8));

        ctx.writeAndFlush("hello String");
        System.out.println("[客户端1]：发送字符串消息");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //接受服务端发送过来的消息
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("[客户端1]:收到服务端" + ctx.channel().remoteAddress() + "的消息:" + byteBuf.toString(CharsetUtil.UTF_8));
    }
}

/**
 * 发送对象示例demo
 */
class ObjectClientHandler extends ChannelInboundHandlerAdapter {
    private TestModel getTestModelObject() {
        TestModel testModel = new TestModel();
        testModel.setId(1);
        testModel.setName("zbw");
        return testModel;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(getTestModelObject());
        System.out.println("[客户端2]:发送TestModel对象");
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //接受服务端发送过来的消息
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("[客户端2]:收到服务端" + ctx.channel().remoteAddress() + "的消息:" + byteBuf.toString(CharsetUtil.UTF_8));
    }
}
